home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / 3dvect39 / 3d1.asm < prev    next >
Encoding:
Assembly Source File  |  1994-10-30  |  36.5 KB  |  1,161 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : 3d1.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : 3d vector routines - fast sort method
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ; - objects cannot enter inside one another
  24. ; - maxsurfs and maxpoints can be kept low - set to largest object requirement
  25. ;
  26. ; To use:
  27. ;
  28. ;          call _land_draw          ; draw _background landscape
  29. ;          call _clearfill          ; clear video memory (last screen)
  30. ;          call _look_at_it         ; make camera look at selected object
  31. ;          call _setsincose         ; set rotation multipliers for eye
  32. ;          call _star_plot          ; plot _background stars (if you want)
  33. ;          call _makeobjs           ; plot all objects on current screen
  34. ;          call _instant_mouse      ; plot mouse on screen
  35. ;          call _flip_page          ; flip video pages
  36. ;          call _updvectors         ; move objects around, _rotate_point them
  37. ;
  38. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  39.  
  40.          .386p
  41.          jumps
  42.  
  43. code32   segment para public use32
  44.          assume cs:code32, ds:code32
  45.  
  46. ; define externals
  47.  
  48.          include pmode.ext                  ; protected mode externals
  49.          include xmode.ext                  ; xmode externals by matt pritchard
  50.          include irq.ext
  51.  
  52.          extrn _nullpalette:dword
  53.  
  54.          include macros.inc
  55.          include equ.inc
  56.  
  57.          include vars1.inc                  ; labels and such
  58.          align 4
  59.          include tables.inc
  60.          include math.inc                   ; rotate,cos,sin,arctan...
  61.          include xscale.inc
  62.          include poly.inc                   ; common ploygon stuff
  63.  
  64.          public _makeobjs
  65.          public _make1obj
  66.          public _flush_surfaces
  67.          public _init_tables
  68.  
  69. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  70. ; Loadpoints:  Begin loading of points from object definition data into array
  71. ; In:
  72. ;  ESI -> object #
  73. ; Out:
  74. ;  ESI -> offset of connection data
  75. ; Given ESI as object number.  _rotate_point, translate and convert to 3d the points
  76. ; of that object.  returns edi as pointer to sides.
  77. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  78.  
  79.          align 4
  80.  
  81. loadpoints:
  82.          mov bl,v_userotate[esi]             ; rotation type
  83.  
  84.          mov si,v_whatshape[esi*2]           ; get shape
  85.          mov esi,_objbase[esi*4]
  86.  
  87. view_is_not_ok:
  88.          mov eax,[esi]
  89.          add esi,8
  90.  
  91.          cmp eax,zad                        ; check if too far to see detail anyway
  92.          jb s view_is_not_ok
  93.  
  94.          mov eax,[esi-4]
  95.          add esi,eax
  96.  
  97.          lodsd
  98.          mov w numpoints,ax
  99.          or ax,ax
  100.          jz no_points_anyway                ; object is made totally out of iterations...
  101.          shr eax,16
  102.          mov numsides,eax
  103.          add esi,50                         ; skip extra data
  104.  
  105.          mov edi,4                          ; reset xp pointer
  106. middle_load_points:
  107.          test bl,no_rotation
  108.          jnz s np13                         ; use different loop if no rotation
  109. np12:
  110.          movsx ebx,w [esi]                  ; x
  111.          movsx ecx,w [esi+2]                ; y
  112.          movsx ebp,w [esi+4]                ; z
  113.  
  114.          push edi esi
  115.          call _rotate_point                 ; _rotate_point
  116.          add ebp,zad
  117.  
  118.          cmp ebp,ztruncate
  119.          jl s ntrt
  120. ntrunct:
  121.          add ebx,xad
  122.          add ecx,yad
  123.          call _make3d
  124.          pop esi edi
  125.          mov xp[edi],ebx
  126.          mov yp[edi],ecx
  127.          mov zp[edi],ebp
  128.          add edi,4                          ; inc xp indexer
  129.          add esi,6                          ; inc input pointer
  130.          dec numpoints
  131.          jne s np12
  132.  
  133.          mov pointindex,edi                 ; save in case of iteration surfaces
  134.  
  135.          ret                                ; edi exits with pointer to sides
  136. ntrt:
  137.          mov ebp,ztruncate
  138.          jmp s ntrunct
  139.  
  140. no_points_anyway:
  141.          mov pointindex,4                   ; side is all iteration surfaces
  142.          shr eax,16
  143.          mov numsides,eax
  144.          add esi,25*2                       ; skip extra data
  145.          ret
  146. np13:
  147.          movsx ebx,w [esi]                  ; x
  148.          movsx ecx,w [esi+2]                ; y
  149.          movsx ebp,w [esi+4]                ; z
  150.  
  151.          push edi esi
  152.          call _rotate_by_camera             ; rotation matrix already set up! (camera)
  153.          add ebp,zad
  154.  
  155.          cmp ebp,ztruncate
  156.          jl s ntrt2
  157. ntrunct2:
  158.          add ebx,xad
  159.          add ecx,yad
  160.          call _make3d
  161.          pop esi edi
  162.          mov xp[edi],ebx
  163.          mov yp[edi],ecx
  164.          mov zp[edi],ebp
  165.          add edi,4                          ; inc xp indexer
  166.          add esi,6
  167.          dec numpoints
  168.          jne s np13
  169.  
  170.          mov pointindex,edi                 ; save in case of iteration surfaces
  171.  
  172.          ret
  173. ntrt2:
  174.          mov ebp,ztruncate
  175.          jmp s ntrunct2
  176.  
  177. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  178. ; Special surface types/options - make your own
  179. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  180.  
  181.          align 4
  182.  
  183. special_commands dd offset dobitmap         ; 0
  184.          dd offset dobitmap                 ; 1
  185.          dd offset pushmatrix               ; 2
  186.          dd offset popmatrix                ; 3
  187.          dd offset pushlocation             ; 4
  188.          dd offset poplocation              ; 5
  189.          dd offset newobject                ; 6
  190.          dd offset no_new_matrix            ; 7
  191.          dd offset gosub_function           ; 8
  192.          dd offset return_function          ; 9
  193.          dd offset goto_function            ; 10
  194.  
  195. number_ofb dw 5*2                           ; hibitmap
  196.          dw 5*2                             ; lobitmap
  197.          dw 1*2                             ; pushmatrix
  198.          dw 1*2                             ; popmatrix
  199.          dw 1*2                             ; pushlocation
  200.          dw 1*2                             ; poplocation
  201.          dw 1*2                             ; newobject
  202.          dw 1*2                             ; no_new_matrix
  203.          dw ?                               ; gosub_function
  204.          dw ?                               ; return_function
  205.          dw ?                               ; goto_function
  206.  
  207.          align 4
  208. gosub_function:
  209.          push esi
  210.          movsx eax,w [esi]
  211.          add esi,eax
  212.          jmp return_iteration
  213.  
  214.          align 4
  215. return_function:
  216.          pop esi
  217.          add esi,2
  218.          jmp return_iteration
  219.  
  220.          align 4
  221. goto_function:
  222.          movsx eax,w [esi]
  223.          add esi,eax
  224.          jmp return_iteration
  225.  
  226.          align 4
  227. pushmatrix:
  228.          push _vmatrix+0
  229.          push _vmatrix+4
  230.          push _vmatrix+8
  231.          push _vmatrix+12
  232.          push _vmatrix+16
  233.          push _vmatrix+20
  234.          push _vmatrix+24
  235.          push _vmatrix+28
  236.          push _vmatrix+32
  237.          jmp return_iteration
  238.  
  239.          align 4
  240. popmatrix:
  241.          pop _vmatrix+32
  242.          pop _vmatrix+28
  243.          pop _vmatrix+24
  244.          pop _vmatrix+20
  245.          pop _vmatrix+16
  246.          pop _vmatrix+12
  247.          pop _vmatrix+8
  248.          pop _vmatrix+4
  249.          pop _vmatrix+0
  250.          jmp return_iteration
  251.  
  252.          align 4
  253. pushlocation:
  254.          push xad
  255.          push yad
  256.          push zad
  257.          jmp return_iteration
  258.  
  259.          align 4
  260. poplocation:
  261.          pop zad
  262.          pop yad
  263.          pop xad
  264.          jmp return_iteration
  265.  
  266.          align 4
  267. ld_special:
  268.          mov ecx,eax
  269.          and ecx,special-1                  ; maximum 127 "special" commands
  270.          jmp [special_commands+ecx*4]
  271.  
  272.          align 4
  273.  
  274. ; handle loading of bitmap from object list
  275. ;
  276. ; eg dw himap,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  277.  
  278. dobitmap:
  279.          lodsw                              ; get from si, first is point
  280.          shl eax,2
  281.          stosw                              ; put in sides table
  282.  
  283.          mov edx,ebp                        ; save indexer
  284.          movzx ebp,ax                       ; get point indexers
  285.          mov eax,zp[ebp]
  286.          mov zeds[ebx*2],eax                ; set zed for sort.
  287.          mov ebp,edx
  288.  
  289.          movsw                              ; get bitmap type
  290.          movsd                              ; get x then y scaling
  291.  
  292.          mov edx,command                    ; get command (for iteration bits)
  293.          mov textures[ebx],dx               ; command is now texture
  294.  
  295.          jmp ln3
  296.  
  297. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  298. ; Loadsides: Load connection data from object data definition
  299. ; In:
  300. ;  ESI -> offset of connection data
  301. ; Out: null
  302. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  303.  
  304.          align 4
  305. loadsides:
  306.          mov _showing,0                     ; reset counter/indexer
  307.          mov lamflag,no
  308.  
  309.          xor ebp,ebp                        ; indexer to first point
  310.          mov edi,offset sides               ; get ready for lodsw and stosw
  311.          xor ebx,ebx
  312. ld_lp:
  313.          lodsw                              ; get command word
  314.          mov command,eax
  315.          mov edx,eax                        ; save for later test
  316.  
  317.          mov order[ebx*2],ebx               ; set order to 0,2,4,6,8...
  318.  
  319.          test eax,special                   ; if bitmap, do special load, or previous
  320.          jnz ld_special                     ; colour (avoids pre-fetch instruction flush)
  321.  
  322.          mov eax,[esi]                      ; get texture data/type
  323.          mov texture12,eax
  324.  
  325.          mov eax,[esi+4]                    ; get colour, high byte is other side
  326.          add esi,8
  327.          mov colors12,eax
  328.  
  329.          push ebp
  330.          push ebx
  331.  
  332.          movzx eax,w [esi]                  ; get from esi, first is unconditinal
  333.          add esi,2
  334.          shl eax,2
  335.          mov [edi],ax                       ; put in edi
  336.          mov [edi+4],ax
  337.          mov ecx,eax
  338.  
  339.          lodsw                              ; get from esi
  340.          shl eax,2
  341.          mov [edi+2],ax                     ; put in edi
  342.          mov [edi+6],ax
  343.          cmp eax,ecx                        ; check all after first point
  344.          je s ld_exitloop
  345.          add edi,4
  346. ld_loop:
  347.          lodsw
  348.          shl eax,2
  349.          mov [edi+0],ax
  350.          cmp eax,ecx
  351.          je s ld_exitloop
  352.  
  353.          lodsw
  354.          shl eax,2
  355.          mov [edi+2],ax
  356.          cmp eax,ecx
  357.          je s ld_exitloop
  358.  
  359.          lodsw
  360.          shl eax,2
  361.          mov [edi+4],ax
  362.          add edi,6
  363.          cmp eax,ecx
  364.          jne s ld_loop
  365.  
  366. ld_exitloop:
  367.          push esi
  368.          mov edi,ebp                        ; adjust bp into appropriate indexer
  369.          mov bp,[sides+edi+6]
  370.          mov ecx,[zp+ebp]
  371.          mov bp,[sides+edi+4]
  372.          add ecx,[zp+ebp]
  373.          mov bp,[sides+edi+2]               ; get point indexers
  374.          add ecx,[zp+ebp]                   ; take average of 4 z values, should be
  375.          mov bp,[sides+edi+0]               ; average of all but two is ok.
  376.          add ecx,[zp+ebp]
  377.          mov zeds[ebx*2],ecx                ; but any will do.
  378.  
  379.          test edx,onscr                     ; find if test is for on screen pixels
  380.          jnz test_if_on_screen
  381.          test dl,both                       ; check if always visible (or point, or line)
  382.          jnz its_line
  383.  
  384. return_screen:
  385.          mov edx,[xp+ebp]                   ; first point
  386.          mov ebx,[yp+ebp]
  387.  
  388.          mov bp,[sides+edi+2]
  389.          mov esi,[xp+ebp]                   ; second point
  390.          mov ecx,[yp+ebp]
  391.  
  392.          mov bp,[sides+edi+4]
  393.          mov edi,[xp+ebp]                   ; third point
  394.          mov ebp,[yp+ebp]
  395.  
  396.          call checkfront                    ; check if side is visible using p1,2,3
  397.  
  398.          pop esi ebx ebp
  399.  
  400.          mov edx,command
  401.          or ecx,ecx
  402.          jle s test_shading                 ; cx>-1 if side visible, skip if not
  403.          test edx,double                    ; test to use other colour
  404.          jz s skipit                        ; miss this side...
  405.          shr texture12,16
  406.          shr colors12,16
  407.          xor w texture12,inverse            ; do inverse shading
  408. test_shading:
  409.          test texture12,shade+last
  410.          jnz handle_shading                 ; shading bit set, do it...
  411. ln2:
  412.          test edx,check                     ; find out if side is only a test side
  413.          jnz s no_show
  414.  
  415.          mov eax,texture12                  ; another side added...
  416.          mov textures[ebx],ax
  417.          movzx eax,w colors12
  418.          add eax,palxrefx                  ; get offset of palette cross reference table for this object
  419.          mov ax,[eax]
  420.          mov surfcolors[ebx],ax
  421. ln3:
  422.          inc _showing
  423.          add ebx,2
  424.          add ebp,maxpolys*2                 ; bump ebp to next block
  425. no_show:
  426.          test edx,iterate
  427.          jnz handle_surface_iteration
  428. skipit:
  429.          test edx,normal                    ; do we skip surface normal data
  430.          jz s no_norml
  431.          add esi,6
  432. no_norml:
  433.          test edx,iterate
  434.          jnz failed_iteration               ; skip iteration data if surface failure
  435.  
  436. return_iteration:
  437.          mov edi,ebp                        ; set di for next stosw
  438.          add edi,offset sides
  439.  
  440.          dec numsides                       ; count for next side
  441.          jne ld_lp
  442.  
  443.          ret
  444.  
  445.          align 4
  446. its_line:
  447.          pop esi ebx ebp
  448.          test w texture12,shade+last
  449.          jz ln2
  450.  
  451. ; handle gourad/_lambert shading
  452.  
  453.          align 4
  454. handle_shading:
  455.          test w texture12,last              ; test to use previous colour or bitmap call
  456.          jnz ld_do_previous
  457.  
  458.          test w texture12,wavey
  459.          jnz ln2
  460.  
  461.          push ebx esi ebp edx
  462.  
  463.          cmp lamflag,no                     ; is _lambert matrix set up?
  464.          je s setitup                       ; jump to less likely route
  465. returnq:
  466.          mov bx,word ptr [esi]              ; get surface normal
  467.          mov cx,word ptr [esi+2]
  468.          mov bp,word ptr [esi+4]
  469.          add esi,6
  470.  
  471.          call _l_rotate_point               ; _rotate_point surface normal by _lambert matrix
  472.  
  473.          pop edx
  474.          test w texture12,inverse           ; have the sides flipped?
  475.          jnz s invert_colour                ; jump to least likely route
  476. lp_contin:
  477.          add edi,256
  478.          shr edi,1                          ; result -256 to +256, turn into 0-256
  479.          mov al,b shading_tables[edi]       ; now into 0-15
  480.          xor ah,ah
  481.          mov lastshade,al
  482.  
  483.          pop ebp esi ebx
  484.  
  485.          add w colors12,ax                  ; user can have offset color in object!
  486.  
  487.          jmp ln2
  488.  
  489.          align 4
  490. invert_colour: ; inversion occures with other side option,
  491.          neg edi                            ; always visible option, and shading option
  492.          jmp lp_contin                      ; all combined!
  493.  
  494.          align 4
  495. setitup:
  496.          push esi
  497.          mov esi,currobj                    ; this is object # from _make1obj
  498.          call _lambert                      ; set up _lambert maxtrix
  499.          mov lamflag,yes
  500.          pop esi
  501.          jmp s returnq
  502.  
  503.          align 4
  504.  
  505. ld_do_previous:
  506.          mov al,lastshade                   ; use colour from previous calculation
  507.          add b colors12,al
  508.          jmp ln2
  509.  
  510. ; handle iteration option
  511.  
  512.          align 4
  513.  
  514. handle_surface_iteration:
  515.          test edx,normal
  516.          jz s no_norml2
  517.          add esi,6                          ; skip if shading normal present
  518. no_norml2:
  519.          test edx,matrix                    ; test to derive new matrix
  520.          jz no_new_matrix
  521. newobject:
  522.          mov edi,currobj                    ; new matrix, get offset object number
  523.          add di,[esi+16]
  524.          test v_onoff[edi],sub_object_on     ; test if sub-object has been turned on...
  525.          jz failed_iteration
  526.  
  527.          mov eax,[esi+24]
  528.          mov minzc,eax
  529.          mov eax,[esi+28]
  530.          mov btolr,eax
  531.          push ebx esi ebp edx               ; save stuff before iteration handle
  532.  
  533.          mov bx,w v_xs[edi*4]                ; get rotation location
  534.          mov cx,w v_ys[edi*4]
  535.          mov bp,w v_zs[edi*4]
  536.          add bx,[esi+10]
  537.          add cx,[esi+12]
  538.          add bp,[esi+14]
  539.          movsx ebx,bx
  540.          movsx ecx,cx
  541.          movsx ebp,bp
  542.  
  543.          push edi
  544.          call _rotate_point                 ; z<>0, find rotation location
  545.  
  546.          add xad,ebx
  547.          add yad,ecx
  548.          add zad,ebp
  549.  
  550.          pop esi                            ; return object number+offset
  551.          test v_userotate[esi],no_rotation   ; test to use new matrix or add to old
  552.          jnz do_compound_thingy
  553.          call _temp_matrix                  ; add to old
  554.          call _matrix_multiply
  555.          mov eax,minzc
  556.          cmp zad,eax                        ; check if new object will be behind camera
  557.          jg done_alterq
  558.          jmp failed_iterationq
  559.  
  560. do_compound_thingy:
  561.          call _compound                     ; _compound new matrix
  562.          mov eax,minzc
  563.          cmp zad,eax                        ; check if new object will be behind camera
  564.          jg done_alterq
  565.          jmp failed_iterationq
  566.  
  567. no_new_matrix:
  568.          test b [esi+8],centroid            ; is there a centroid offset?
  569.          jz done_alter
  570.          mov eax,[esi+28]
  571.          mov btolr,eax
  572.  
  573.          push ebx esi ebp edx               ; save stuff before centroid handle
  574.          movsx ebx,w [esi+10]               ; no new matrix command, find point
  575.          movsx ecx,w [esi+12]               ; offset (addition)
  576.          movsx ebp,w [esi+14]
  577.  
  578.          call _rotate_point                 ; if found, add _rotate_pointd point to xad,yad,zad
  579.  
  580.          add xad,ebx
  581.          add yad,ecx
  582.          add zad,ebp
  583.  
  584. done_alterq:
  585.          sub zad,1                          ; prevent huge object from becoming 0
  586.          adc zad,1
  587.  
  588.          mov ebx,xad                        ; test if new xad,yad,zad are within screen boundaries
  589.          mov ecx,yad
  590.          mov ebp,zad
  591.  
  592.          cmul eax,ebx,ratiox                ; use fast constant multiply fo 3d conversion
  593.          idiv ebp
  594.  
  595.          movsx edx,_xmins
  596.          sub edx,btolr
  597.          cmp eax,edx                        ; tolerance is max object size/ratio
  598.          jl failed_iterationq
  599.          movsx edx,_xmaxs
  600.          add edx,btolr
  601.          cmp eax,edx
  602.          jge failed_iterationq
  603.  
  604.          mov ebx,eax
  605.  
  606.          cmul eax,ecx,ratioy
  607.          idiv ebp
  608.  
  609.          movsx edx,_ymins
  610.          sub edx,btolr
  611.          cmp eax,edx
  612.          jl failed_iterationq
  613.          movsx edx,_ymaxs
  614.          add edx,btolr
  615.          cmp eax,edx
  616.          jge failed_iterationq
  617.  
  618.          mov edi,pointindex
  619.          mov xp[edi],ebx
  620.          mov yp[edi],eax
  621.          mov zp[edi],ebp
  622.          add pointindex,4
  623.  
  624.          pop edx ebp esi ebx
  625.  
  626. done_alter:
  627.          movzx eax,w [esi]                  ; get number of extra points in iteration
  628.          add esi,2
  629.          mov numpoints,eax                  ; set as counter
  630.          mov ecx,eax                        ; save number of extra points for later use
  631.  
  632.          shl eax,2
  633.          add eax,pointindex                 ; pointindex = word indexer to last point
  634.          cmp eax,maxpoints*4                ; test for overflow in points tables
  635.          jae abort_all2
  636.  
  637.          lodsw                              ; get number of sides in iteration
  638.          add numsides,eax
  639.  
  640.          add eax,_showing
  641.          cmp eax,maxsurfaces-1              ; check for overflow in "sides" tables
  642.          jae abort_all2
  643.  
  644.          add esi,25*2
  645.  
  646.          or ecx,ecx                         ; no new points to add? (just surfaces)
  647.          je return_iteration                ; only sides added to iteration, done...
  648.  
  649.          push ebx ebp edx                   ; save load and store locations
  650.  
  651.          mov edi,currobj                    ; add more points to xp,yp,zp list
  652.          mov bl,v_userotate[edi]             ; because iteration is visible
  653.  
  654.          mov edi,pointindex                 ; movzx edi,pointindex
  655.  
  656.          call middle_load_points
  657.          pop edx ebp ebx
  658.  
  659.          jmp return_iteration
  660.  
  661.          align 4
  662.  
  663. abort_all2:
  664.          ret                                ; out of room for surfaces, return and plot
  665.  
  666. ; perform test for option "onscr" - test if polygon points on screen.
  667. ; routine also tests if polygon crosses screen - eg no point is on the screen
  668. ; but the polygon covers the screen, like the front of a very big building.
  669.  
  670.          align 4
  671.  
  672. test_if_on_screen:
  673.          xor bl,bl                          ; bl = quadrant flag
  674.          push edx edi                       ; save command
  675.  
  676.          mov esi,ebp
  677. tios:
  678.          mov ecx,xp[esi]                    ; cx, dx =(x,y) to test
  679.          mov edx,yp[esi]
  680.  
  681.          mov ah,32                          ;  32 16  8    determine where point is,
  682.          cmp cx,_xmins                      ;1  x  x  x    then or bl with location
  683.          jl s ytest                         ;2  x  x  x
  684.          mov ah,8                           ;4  x  x  x
  685.          cmp cx,_xmaxs                      ;
  686.          jge s ytest
  687.          mov ah,16
  688. ytest:
  689.          mov al,1
  690.          cmp dx,_ymins
  691.          jl s oritall
  692.          mov al,4
  693.          cmp dx,_ymaxs
  694.          jge s oritall
  695.  
  696.          cmp ah,16
  697.          je s on_screen                     ; a point is on the screen, generate side...
  698.          mov al,2
  699. oritall:
  700.          or bl,ah                           ; point is not on the screen, but it may
  701.          or bl,al                           ; contribute to a polygon which covers the screen.
  702.  
  703.          add edi,2                          ; get next connection for another test
  704.          mov si,sides[edi]
  705.          cmp si,bp                          ; test if at last connection in iteration test
  706.          jne tios
  707.  
  708.          xor al,al                          ; count number of bits in y (must be >2)
  709.          ror bl,1
  710.          adc al,0
  711.          ror bl,1
  712.          adc al,0
  713.          ror bl,1
  714.          adc al,0
  715.          cmp al,1
  716.          jbe s skipit2
  717.  
  718.          xor al,al                          ; now count x (must be >2)
  719.          ror bl,1
  720.          adc al,0
  721.          ror bl,1
  722.          adc al,0
  723.          ror bl,1
  724.          adc al,0
  725.          cmp al,1
  726.          jbe s skipit2
  727. on_screen:
  728.          pop edi edx
  729.  
  730.          test edx,both                      ; side is on screen
  731.          jz return_screen                   ; test if alway visible
  732.  
  733.          pop esi ebx ebp                    ; always, pop and test for shading
  734.          test edx,shade
  735.          jz ln2                             ; no shading - do normal return
  736.          jmp handle_shading
  737.  
  738. skipit2:
  739.          pop edi edx esi ebx ebp
  740.          jmp skipit
  741.  
  742. ; handle failure of iteration option
  743.  
  744.          align 4
  745.  
  746. failed_iterationq:
  747.          pop edx ebp esi ebx
  748.  
  749. failed_iteration:
  750.          movzx ecx,w [esi+4]                ; number of bytes to skip in case of failure
  751.          mov ax,[esi+6]                     ; get number of points TOTAL in iteration
  752.          add esi,8
  753.          shl eax,2                          ; in case iteration in iteration in iteration...
  754.          add w pointindex,ax
  755.          add esi,ecx
  756.          jmp return_iteration
  757.  
  758.          align 4
  759.  
  760. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  761. ; _make1obj: Handle plotting of object ESI
  762. ; In:
  763. ;   ESI -> object #
  764. ; OUT:null
  765. ; Notes:
  766. ; Routine assumes object is already ON!  note: esi not si!
  767. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  768.  
  769. _make1obj:
  770.          mov currobj,esi
  771.  
  772.          mov ebx,v_xs[esi*4]                 ; displacement
  773.          sub ebx,eyex
  774.          mov ecx,v_ys[esi*4]
  775.          sub ecx,eyey
  776.          mov ebp,v_zs[esi*4]
  777.          sub ebp,eyez
  778.  
  779.          test v_userotate[esi],s_himap+s_point ; check if bitmap or point
  780.          jnz mo_special
  781.  
  782.          if div_256 eq 8
  783.          shr ebx,8                          ; account for decimal places
  784.          test ebx,00800000h
  785.          jz s pm_1
  786.          or ebx, 0ff000000h
  787. pm_1:
  788.          shr ecx,8
  789.          test ecx,00800000h
  790.          jz s pm_2
  791.          or ecx, 0ff000000h
  792. pm_2:
  793.          shr ebp,8
  794.          test ebp,00800000h
  795.          jz s pm_3
  796.          or ebp, 0ff000000h
  797. pm_3:
  798.          endif
  799.  
  800.          mov si,v_whatshape[esi*2]           ; get shape
  801.          mov esi,_objbase[esi*4]            ; get header start
  802.          add esi,[esi+4]                    ; get first resolution
  803.          mov edi,[esi+14*2]                 ; get maximum distance seen
  804.  
  805.          cmp ebx,edi                        ; check if within visible space
  806.          jnl s noa2                         ; if object miles away, don't bother
  807.          cmp ebp,edi
  808.          jnl s noa2
  809.          cmp ecx,edi
  810.          jnl s noa2
  811.          neg edi
  812.          cmp ebp,edi
  813.          jl s noa2
  814.          cmp ebx,edi
  815.          jl s noa2
  816.          cmp ecx,edi
  817.          jg s mo_misout
  818. noa2:
  819.          ret
  820. mo_misout:
  821.          mov edi,dword ptr [esi+16*2]
  822.          mov eax,dword ptr [esi+18*2]
  823.          mov btolr,eax
  824.          call _zsolve                       ; figure out camera displacement
  825.          cmp esi,edi                        ; check if behind camera, miminum dist.
  826.          jl s noa2
  827.  
  828.          sub esi,1                          ; make z non-zero
  829.          adc esi,1
  830.  
  831.          call _xsolve
  832.          mov xad,edi                        ; store 3d offsets
  833.          call _make3dx                      ; now make object farther in 3d
  834.  
  835.          movsx eax,_xmins
  836.          sub eax,btolr
  837.          cmp edi,eax                        ; tolerance is max object size/ratio
  838.          jl s noa2
  839.          movsx eax,_xmaxs
  840.          add eax,btolr
  841.          cmp edi,eax
  842.          jge s noa2
  843.  
  844.          call _ysolve                       ; solve y and set correct regs
  845.          mov yad,ecx
  846.          call _make3dy                      ; now make object farther in 3d
  847.  
  848.          movsx eax,_ymins
  849.          sub eax,btolr
  850.          cmp ecx,eax
  851.          jl noa2
  852.          movsx eax,_ymaxs
  853.          add eax,btolr
  854.          cmp ecx,eax
  855.          jge noa2
  856.  
  857.          mov zad,ebp
  858.          mov zedthis,ebp                    ; store z for next sort
  859.  
  860.          mov xp,ebx                         ; save center of gravity as point 0
  861.          mov yp,ecx
  862.          mov zp,ebp
  863.  
  864.          mov esi,currobj                    ; pop original object number
  865.          xor ebx,ebx
  866.          mov bl,v_palxref[esi]
  867.          mov ebx,_xreftable[ebx*4]
  868.          mov palxrefx,ebx
  869.  
  870.          test v_userotate[esi],no_rotation   ; test to call _compound routine
  871.          jnz s mk_skipc                     ; skip if anything other than full rotations
  872.          call _compound                     ; full rotation object, calc. matrix
  873. mk_skipc:
  874.          call loadpoints                    ; load points and _rotate_point, exit di=sides
  875.          call loadsides                     ; now load sides, starting at di
  876.          call _sortlist                     ; sort surfaces
  877.          jmp _drawvect                      ; draw surfaces and exit
  878. noa:
  879.          ret
  880.  
  881. ; if v_userotate = "bitmap" then draw bitmap at location x,y,z
  882.  
  883.          align 4
  884.  
  885. mo_special:
  886.          mov edi,maxz*256
  887.          cmp ebx,edi                        ; check if within visible space
  888.          jnl s noa                          ; if object miles away, don't bother
  889.          cmp ebp,edi
  890.          jnl s noa
  891.          cmp ecx,edi
  892.          jnl s noa
  893.          neg edi
  894.          cmp ebp,edi
  895.          jl s noa
  896.          cmp ebx,edi
  897.          jl s noa
  898.          cmp ecx,edi
  899.          jl s noa
  900.  
  901.          if div_256 eq 8
  902.          shr ebx,8                          ; account for decimal places, /256
  903.          test ebx,00800000h
  904.          jz s pq_1
  905.          or ebx, 0ff000000h
  906. pq_1:
  907.          shr ecx,8
  908.          test ecx,00800000h
  909.          jz s pq_2
  910.          or ecx, 0ff000000h
  911. pq_2:
  912.          shr ebp,8
  913.          test ebp,00800000h
  914.          jz s pq_3
  915.          or ebp, 0ff000000h
  916. pq_3:
  917.          endif
  918.  
  919.          call _zsolve                       ; figure out camera displacement
  920.  
  921.          cmp esi,minz                       ; check if behind camera, miminum dist.
  922.          jl noa2
  923.  
  924.          call _xsolve
  925.          mov xad,edi                        ; store 3d offsets
  926.          call _make3dx                      ; now make object farther in 3d
  927.  
  928.          cmp edi,xmit                       ; tolerance is max object size/ratio
  929.          jl noa
  930.          cmp edi,xmat
  931.          jge noa
  932.  
  933.          call _ysolve                       ; solve y and set correct regs
  934.          mov yad,ecx
  935.          call _make3dy                      ; now make object farther in 3d
  936.  
  937.          cmp ecx,ymit
  938.          jl noa
  939.          cmp ecx,ymat
  940.          jge noa
  941.  
  942.          mov zad,ebp
  943.          mov zedthis,ebp                    ; store z for next sort
  944.          mov esi,currobj                    ; pop original object number
  945.  
  946.          mov al,v_userotate[esi]
  947.          test al,s_point                    ; check if point
  948.          jnz mo_ispoint
  949.  
  950.          push eax ebx ecx                   ; save actual center of bitmap and command
  951.  
  952.          mov ebx,xad                        ; calc size of bitmap
  953.          mov ecx,yad
  954.  
  955.          shl esi,1                          ; si = word
  956.          movzx edx,v_bitobjx[esi]           ; get addition for bitmap size
  957.          sub ebx,edx
  958.          movzx edx,v_bitobjy[esi]           ; get addition for bitmap size
  959.          sub ecx,edx
  960.  
  961.          mov si,v_whatshape[esi]
  962.          shl esi,2                          ; si = dword
  963.          sub ebx,_bitx[esi]
  964.          sub ecx,_bity[esi]                 ; ebx,ecx = top corner of bitmap in 3d
  965.  
  966.          mov eax,_bitbase[esi]
  967.          mov _bitmap,eax
  968.  
  969.          call _make3d                       ; ebx,ecx = top corner of bitmap in 2d
  970.  
  971.          pop ebp eax                        ; bp = y, ax = x center
  972.          sub bp,cx                          ; bp = y height/2
  973.          sub ax,bx                          ; ax = x width/2
  974.          mov _scale_destheight,bp
  975.          mov _scale_destwidth,ax
  976.  
  977.          movsx ebp,bp
  978.          movsx eax,ax
  979.          shr eax,1
  980.          shr ebp,1
  981.          add cx,bp
  982.          add bx,ax
  983.  
  984.          add bx,_xcent
  985.          add cx,_ycent
  986.          mov _scale_destx,bx
  987.          mov _scale_desty,cx
  988.  
  989.          pop eax
  990.          test al,lomap-himap                ; test to use 1/4 scale bitmap or full scale
  991.          jz _xscale2
  992.          jmp _xscale4
  993. noa7:
  994.          ret
  995. mo_ispoint:
  996.          cmp bx,_xmins                      ; draw single point/bullet
  997.          jl s noa7
  998.          cmp bx,_xmaxs
  999.          jge s noa7
  1000.          cmp cx,_ymins
  1001.          jl s noa7
  1002.          cmp cx,_ymaxs                      ; _ymaxs1 if larger pixel
  1003.          jge s noa7
  1004.  
  1005.          mov edi, _current_page             ; point to active vga page
  1006.          add bx,_xcent
  1007.          add cx,_ycent
  1008.  
  1009.          mov si,cx
  1010.          mov eax,[esi*4+_fastimultable]     ; get offset to start of line
  1011.  
  1012.          mov cx, bx                         ; copy to extract plane # from
  1013.          shr bx, 2                          ; x offset (bytes) = xpos/4
  1014.          add bx, ax                         ; offset = width*ypos + xpos/4
  1015.  
  1016.          mov ax, map_mask_plane1            ; map mask & plane select register
  1017.          and cl, plane_bits                 ; get plane bits
  1018.          shl ah, cl                         ; get plane select value
  1019.          out_16 sc_index, ax                ; select plane
  1020.  
  1021.          movzx ebx,bx
  1022.          mov [edi+ebx],b bulletcolour       ; draw pixel, red or yellow is good
  1023. ;        add edi,xactual/4
  1024. ;        mov [edi+ebx],b bulletcolour2      ; draw larger bullet/pixel
  1025.  
  1026. ; if drawing larger pixel, change above code to this!
  1027. ;        cmp cx,_ymaxs1
  1028. ;        jge s noa7
  1029.  
  1030.          ret
  1031.  
  1032.          align 4
  1033.  
  1034. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1035. ; Setmakeorder: Initialize original order for plotting objects
  1036. ;  In=Out=null
  1037. ; Notes:  This is called by _init_tables so there is no need for you to do it.
  1038. ; This  must  be  called  once  at  the  beginging of the program  to  define
  1039. ; in what order the objects must be plotted (back to front).   The  order  is
  1040. ; constantly being re-arranged as objects move in front an behind one another
  1041. ; If you want to do windowing, save the makeorder table for each window.
  1042. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1043.  
  1044. setmakeorder:
  1045.  
  1046.          i=0
  1047.          rept maxobjects                    ; macro to produce unrolled loop
  1048.          mov makeorder+i*4,i+1              ; set makeorder to 0,1,2,3,4
  1049.          i=i+1
  1050.          endm
  1051.  
  1052.          ret
  1053.  
  1054.          align 4
  1055.  
  1056. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1057. ; _makeobjs: Make/plot all objects on _current_page
  1058. ;  In=Out=null
  1059. ; Notes: Called from your mainline animation routine, falls through to sort
  1060. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1061.  
  1062. _makeobjs:                                  ; make all objects, unrolled loop
  1063.          xor esi,esi
  1064.          i=0
  1065.  
  1066.          rept maxobjects
  1067.          local itsoff
  1068.  
  1069.          mov eax,7fffffffh                  ; in case of abort
  1070.          mov esi,makeorder+i*4
  1071.          test v_onoff[esi],mainobject_on    ; check on/off
  1072.          jz s itsoff
  1073.  
  1074.          call _make1obj
  1075.          mov eax,zedthis                    ; get z and save for re_sort
  1076.          xor esi,esi
  1077. itsoff:
  1078.          mov finalzed+i*4,eax
  1079.  
  1080.          i=i+1
  1081.          endm
  1082.  
  1083. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1084. ; Re_sort:Bubble sort for entire objects, fastest when already sorted (assumed)
  1085. ;  In=Out=null
  1086. ; Notes: No need to ever call this routine as _makeobjs falls through to here.
  1087. ; This routine sorts the objects make order by the previous Z distance.
  1088. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1089.  
  1090.          basedif equ makeorder-finalzed
  1091. re_sort:
  1092.          mov edi,maxobjects*4+offset finalzed
  1093.          mov esi,maxobjects
  1094.          mov ecx,maxobjects+2
  1095.          mov edx,offset finalzed-4-4
  1096. rs_loop1:
  1097.          dec esi
  1098.          sub edi,4
  1099.          mov eax,makeorder[esi*4]
  1100.          test v_onoff[eax],mainobject_on
  1101.          loopz s rs_loop1
  1102.          jcxz _ret
  1103.  
  1104.          mov esi,-1
  1105. rs_loop2:
  1106.          inc esi
  1107.          add edx,4
  1108.          mov eax,makeorder[esi*4]
  1109.          test v_onoff[eax],mainobject_on
  1110.          loopz s rs_loop2
  1111.          jcxz _ret
  1112.  
  1113.          xor ebx,ebx                        ; sort flag
  1114. nextccx:
  1115.          mov esi,edx
  1116.          add edx,4
  1117. nextddx:
  1118.          add esi,4
  1119.  
  1120.          mov eax,[esi+4]
  1121.          cmp eax,[esi]
  1122.          jle s donotng
  1123.          xchg eax,[esi]                     ; don't flip entire object, just indexers
  1124.          xchg eax,[esi+4]
  1125.          mov eax,basedif[esi+4]
  1126.          xchg eax,basedif[esi]
  1127.          xchg eax,basedif[esi+4]
  1128.          inc ebx                            ; flag that one sorted
  1129. donotng:
  1130.          cmp esi,edi
  1131.          jb s nextddx
  1132.  
  1133.          or ebx,ebx                         ; re-sort until no more sorts
  1134.          loopne s nextccx
  1135. quickex:
  1136.          ret
  1137.  
  1138. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1139. ; _init_tables: Initialize ordering before beginning 3d animation
  1140. ;  In=Out=null
  1141. ; Notes: Called by YOU. Different routines between 3d1,3d2 and 3d3
  1142. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1143.  
  1144. _init_tables:
  1145.          call setmakeorder
  1146.          ret
  1147.  
  1148. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1149. ; _flush_surfaces: Sort and flush all surfaces from polygon buffer to screen
  1150. ;  In=Out=null
  1151. ; Notes: called by _make1obj
  1152. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1153.  
  1154. _flush_surfaces:
  1155.          call _sortlist                     ; sort sides according to z distance
  1156.          call _drawvect                     ; draw 'em on da screen
  1157.          ret
  1158.  
  1159. code32   ends
  1160.          end
  1161.